# Description: 一个简单的 Selenium 脚本，用于下载知网搜索结果中的 PDF 文件。
# Author: TMRNic
# Date: 2021-07-15
# Version: 1.0
# Declaration: 
## Usage Rights Statement: For Educational and Research Purposes Only

from seleniumbase import Driver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import random

def bot_wait():
    """
    使程序暂停一段时间，以模拟人类用户的行为。
    暂停时间随机，介于3.0到5.0秒之间，使机器人的行为更加自然和难以预测。
    """
    time.sleep(random.uniform(3.0, 5.0))

def new_tab(driver):
    """
    在当前浏览器中新建一个标签页，并将driver的控制权切换到新标签页上。

    :param driver: WebDriver对象，用于控制浏览器。
    """
    # 执行JavaScript脚本在当前浏览器中打开一个新标签页。
    driver.execute_script("window.open('');")
    # 切换driver的控制权到最新打开的标签页。
    driver.switch_to_window(driver.window_handles[-1])

# Script - 主程序 ------------------------------
# 初始化 Edge 浏览器
driver = Driver(browser="edge", headed=True)  # 设置下载文件夹
wait = WebDriverWait(driver, 30)  # 最大等待 30 秒
keyword = input("请输入搜索关键词: ")       # 输入搜索关键词
pagenum = 0         # 记录当前页数

try:
    # 打开 CNKI 网站
    # driver.get("https://www.cnki.net")         # 打开知网首页
    driver.get("https://kns.cnki.net/kns8s/?classid=YSTT4HG0")       # 打开期刊文献检索页面
    # 等待页面加载完成
    driver.wait_for_element('input#txt_search.search-input', timeout=10)    # 等待搜索框出现
    # 在搜索框中输入关键词
    driver.type('input#txt_search.search-input', keyword)           # 输入搜索关键词
    
    # 点击搜索按钮
    driver.click('input.search-btn')                 # 点击搜索按钮
    driver.implicitly_wait(5)
    driver.switch_to_window(driver.window_handles[-1])      # 切换到新打开的标签页
    driver.wait_for_element('table.result-table-list', timeout=10)      # 等待搜索结果加载完成
    
    while True:
        # 获取所有搜索结果链接
        bot_wait()
        results = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, "fz14")))
        # 循环网页一页中的条目
        # wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "a.fz14")))
        # # results = driver.find_elements(By.CSS_SELECTOR, "a.fz14")
        # results = driver.find_elements('a.fz14')
        print(f"第 {pagenum+1} 页共找到 {len(results)} 个搜索结果")

        # 遍历搜索结果并下载 PDF
        for i, result in enumerate(results):
            # new_tab(driver)     # 打开新标签页
            bot_wait()          # 随机等待
            # 点击打开详情页面(两种方法)
            result.click()      # Method 1

            # 切换到新打开的标签页
            driver.switch_to_window(driver.window_handles[-1])
            # 等待详情页面加载
            driver.wait_for_element('li.btn-dlpdf', timeout=20)
            # 点击 PDF 下载按钮
            driver.click('li.btn-dlpdf')
            
            # 等待下载对话框弹出（可能需要根据系统调整时间）
            bot_wait()          # 随机等待
            print(f"已下载第 {i + 1} 个结果的 PDF 文件")
            driver.close()      # 关闭当前标签页
            driver.switch_to_window(driver.window_handles[0])  # 切换回搜索结果页面

        # 检查是否有下一页
        bot_wait()          # 随机等待
        next_page = driver.find_element('a#PageNext.pagesnums')     # 查找下一页按钮
        if next_page and pagenum < 10:          # 最多下载10页
            next_page.click()                   # 点击下一页按钮
            driver.implicitly_wait(5)           # 等待页面加载
            pagenum += 1
            print(f"已切换到第 {pagenum+1} 页")     # 输出当前页数
        else:
            print("没有下一页了")
            driver.close()      # 关闭当前标签页，返回搜索结果页面
            driver.switch_to_window(driver.window_handles[0])       # 切换回搜索结果页面
            break
        
except Exception as e:
    print(f"发生错误: {e}")


